<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>MQTT服务器管理面板</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        
        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            min-height: 100vh;
            color: #333;
        }
        
        .container {
            max-width: 1400px;
            margin: 0 auto;
            padding: 20px;
        }
        
        .header {
            background: white;
            border-radius: 15px;
            padding: 30px;
            margin-bottom: 30px;
            box-shadow: 0 10px 30px rgba(0,0,0,0.1);
            text-align: center;
        }
        
        .header h1 {
            color: #4a5568;
            font-size: 2.5em;
            margin-bottom: 10px;
        }
        
        .header p {
            color: #718096;
            font-size: 1.1em;
        }
        
        .status-bar {
            display: flex;
            gap: 20px;
            margin-bottom: 30px;
        }
        
        .status-card {
            flex: 1;
            background: white;
            border-radius: 15px;
            padding: 25px;
            box-shadow: 0 10px 30px rgba(0,0,0,0.1);
            text-align: center;
        }
        
        .status-card h3 {
            color: #4a5568;
            margin-bottom: 15px;
            font-size: 1.2em;
        }
        
        .status-value {
            font-size: 2.5em;
            font-weight: bold;
            margin-bottom: 10px;
        }
        
        .online { color: #48bb78; }
        .offline { color: #f56565; }
        .info { color: #4299e1; }
        
        .tabs {
            display: flex;
            background: white;
            border-radius: 15px 15px 0 0;
            overflow: hidden;
            box-shadow: 0 10px 30px rgba(0,0,0,0.1);
        }
        
        .tab {
            flex: 1;
            padding: 20px;
            background: #f7fafc;
            border: none;
            cursor: pointer;
            font-size: 1.1em;
            font-weight: 600;
            color: #718096;
            transition: all 0.3s ease;
        }
        
        .tab.active {
            background: white;
            color: #4a5568;
        }
        
        .tab-content {
            background: white;
            border-radius: 0 0 15px 15px;
            padding: 30px;
            box-shadow: 0 10px 30px rgba(0,0,0,0.1);
            min-height: 500px;
        }
        
        .tab-panel {
            display: none;
        }
        
        .tab-panel.active {
            display: block;
        }
        
        .device-grid {
            display: grid;
            grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
            gap: 20px;
        }
        
        .device-card {
            background: #f7fafc;
            border-radius: 10px;
            padding: 20px;
            border-left: 4px solid #48bb78;
        }
        
        .device-card.offline {
            border-left-color: #f56565;
        }
        
        .device-card:hover {
            transform: translateY(-3px);
            box-shadow: 0 8px 25px rgba(0,0,0,0.15);
        }
        
        .device-name {
            font-weight: bold;
            font-size: 1.2em;
            margin-bottom: 10px;
            color: #2d3748;
        }
        
        .device-status {
            display: inline-block;
            padding: 4px 12px;
            border-radius: 20px;
            font-size: 0.9em;
            font-weight: 600;
        }
        
        .device-status.online {
            background: #c6f6d5;
            color: #22543d;
        }
        
        .device-status.offline {
            background: #fed7d7;
            color: #742a2a;
        }
        
        .message-log {
            max-height: 400px;
            overflow-y: auto;
            background: #f7fafc;
            border-radius: 10px;
            padding: 20px;
        }
        
        .message-item {
            background: white;
            margin-bottom: 10px;
            padding: 15px;
            border-radius: 8px;
            border-left: 4px solid #4299e1;
        }
        
        .message-item.heart {
            border-left-color: #ed8936;
        }
        
        .message-time {
            font-size: 0.9em;
            color: #718096;
            margin-bottom: 5px;
        }
        
        .message-topic {
            font-weight: bold;
            color: #2d3748;
            margin-bottom: 5px;
        }
        
        .message-payload {
            color: #4a5568;
            font-family: 'Courier New', monospace;
            background: #edf2f7;
            padding: 8px;
            border-radius: 4px;
        }
        
        .data-table {
            width: 100%;
            border-collapse: collapse;
            margin-top: 20px;
        }
        
        .data-table th,
        .data-table td {
            padding: 12px;
            text-align: left;
            border-bottom: 1px solid #e2e8f0;
        }
        
        .data-table th {
            background: #f7fafc;
            font-weight: 600;
            color: #4a5568;
        }
        
        .data-table tr:hover {
            background: #f7fafc;
        }
        
        .publish-form {
            background: #f7fafc;
            padding: 25px;
            border-radius: 10px;
            margin-bottom: 30px;
        }
        
        .form-group {
            margin-bottom: 20px;
        }
        
        .form-group label {
            display: block;
            margin-bottom: 8px;
            font-weight: 600;
            color: #4a5568;
        }
        
        .form-group input,
        .form-group textarea {
            width: 100%;
            padding: 12px;
            border: 2px solid #e2e8f0;
            border-radius: 8px;
            font-size: 1em;
            transition: border-color 0.3s ease;
        }
        
        .form-group input:focus,
        .form-group textarea:focus {
            outline: none;
            border-color: #4299e1;
        }
        
        .btn {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            border: none;
            padding: 12px 24px;
            border-radius: 8px;
            cursor: pointer;
            font-size: 1em;
            font-weight: 600;
            transition: transform 0.2s ease;
        }
        
        .btn:hover {
            transform: translateY(-2px);
        }
        
        .connection-indicator {
            position: fixed;
            top: 20px;
            right: 20px;
            padding: 10px 15px;
            border-radius: 20px;
            font-weight: 600;
            font-size: 0.9em;
        }
        
        .connection-indicator.connected {
            background: #c6f6d5;
            color: #22543d;
        }
        
        .connection-indicator.disconnected {
            background: #fed7d7;
            color: #742a2a;
        }
        
        @media (max-width: 768px) {
            .status-bar {
                flex-direction: column;
            }
            
            .tabs {
                flex-direction: column;
            }
            
            .device-grid {
                grid-template-columns: 1fr;
            }
        }
    </style>
</head>
<body>
    <div class="connection-indicator" id="connectionStatus">连接中...</div>
    
    <div class="container">
        <div class="header">
            <h1>🚀 MQTT服务器管理面板</h1>
            <p>实时监控您的MQTT服务器和设备状态</p>
        </div>
        
        <div class="status-bar">
            <div class="status-card">
                <h3>在线设备</h3>
                <div class="status-value online" id="onlineDevices">0</div>
                <p>设备已连接</p>
            </div>
            <div class="status-card">
                <h3>离线设备</h3>
                <div class="status-value offline" id="offlineDevices">0</div>
                <p>设备已断开</p>
            </div>
            <div class="status-card">
                <h3>今日消息</h3>
                <div class="status-value info" id="todayMessages">0</div>
                <p>消息总数</p>
            </div>
            <div class="status-card">
                <h3>数据记录</h3>
                <div class="status-value info" id="totalRecords">0</div>
                <p>存储记录</p>
            </div>
        </div>
        
        <div class="tabs">
            <button class="tab active" onclick="switchTab('devices')">📱 设备管理</button>
            <button class="tab" onclick="switchTab('messages')">💬 消息日志</button>
            <button class="tab" onclick="switchTab('database')">🗄️ 数据库</button>
            <button class="tab" onclick="switchTab('publish')">📤 消息发布</button>
        </div>
        
        <div class="tab-content">
            <div id="devices" class="tab-panel active">
                <h2>设备状态</h2>
                <div class="device-grid" id="deviceGrid">
                    <!-- 设备列表将在这里动态生成 -->
                </div>
            </div>
            
            <div id="messages" class="tab-panel">
                <h2>实时消息日志</h2>
                <button class="btn" onclick="clearMessages()">清空日志</button>
                <div class="message-log" id="messageLog">
                    <!-- 消息日志将在这里动态生成 -->
                </div>
            </div>
            
            <div id="database" class="tab-panel">
                <h2>数据库概览</h2>
                
                <div class="status-bar">
                    <div class="status-card">
                        <h3>寄存柜</h3>
                        <div class="status-value info" id="boxCount">0</div>
                    </div>
                    <div class="status-card">
                        <h3>操作记录</h3>
                        <div class="status-value info" id="recordCount">0</div>
                    </div>
                    <div class="status-card">
                        <h3>成员</h3>
                        <div class="status-value info" id="memberCount">0</div>
                    </div>
                </div>
                
                <h3>最近操作记录</h3>
                <table class="data-table" id="recordsTable">
                    <thead>
                        <tr>
                            <th>时间</th>
                            <th>柜子ID</th>
                            <th>操作者</th>
                            <th>操作类型</th>
                            <th>访问方式</th>
                        </tr>
                    </thead>
                    <tbody>
                        <!-- 记录将在这里动态生成 -->
                    </tbody>
                </table>
            </div>
            
            <div id="publish" class="tab-panel">
                <h2>发布MQTT消息</h2>
                
                <div class="publish-form">
                    <div class="form-group">
                        <label for="publishTopic">主题 (Topic)</label>
                        <input type="text" id="publishTopic" placeholder="例如: kaihong/devices/cmd/put">
                    </div>
                    
                    <div class="form-group">
                        <label for="publishPayload">消息内容 (Payload)</label>
                        <textarea id="publishPayload" rows="6" placeholder='例如: {"device":"box1","command":{"switch":1},"timestamp":"2023-11-15T10:30:00Z"}'></textarea>
                    </div>
                    
                    <button class="btn" onclick="publishMessage()">发布消息</button>
                </div>
                
                <h3>常用命令模板</h3>
                <div class="device-grid">
                    <div class="device-card" onclick="useTemplate('heart')">
                        <div class="device-name">心跳测试</div>
                        <p>发送心跳信号</p>
                    </div>
                    <div class="device-card" onclick="useTemplate('unlock')">
                        <div class="device-name">开锁命令</div>
                        <p>控制寄存柜开锁</p>
                    </div>
                    <div class="device-card" onclick="useTemplate('status')">
                        <div class="device-name">状态查询</div>
                        <p>查询设备状态</p>
                    </div>
                </div>
            </div>
        </div>
    </div>

    <script>
        let ws = null;
        let currentTab = 'devices';
        
        // 初始化WebSocket连接
        function initWebSocket() {
            try {
                ws = new WebSocket('ws://localhost:8080');
                
                ws.onopen = function() {
                    console.log('✅ WebSocket连接已建立');
                    updateConnectionStatus(true);
                };
                
                ws.onmessage = function(event) {
                    try {
                        const data = JSON.parse(event.data);
                        console.log('📨 收到WebSocket消息:', data);
                        handleWebSocketMessage(data);
                    } catch (error) {
                        console.error('❌ 解析WebSocket消息失败:', error);
                    }
                };
                
                ws.onclose = function() {
                    console.log('🔌 WebSocket连接已断开');
                    updateConnectionStatus(false);
                    // 5秒后尝试重连
                    setTimeout(initWebSocket, 5000);
                };
                
                ws.onerror = function(error) {
                    console.error('❌ WebSocket错误:', error);
                    updateConnectionStatus(false);
                };
            } catch (error) {
                console.error('❌ WebSocket初始化失败:', error);
                updateConnectionStatus(false);
                // 5秒后尝试重连
                setTimeout(initWebSocket, 5000);
            }
        }
        
        // 更新连接状态
        function updateConnectionStatus(connected) {
            const indicator = document.getElementById('connectionStatus');
            if (connected) {
                indicator.textContent = '🟢 已连接';
                indicator.className = 'connection-indicator connected';
            } else {
                indicator.textContent = '🔴 已断开';
                indicator.className = 'connection-indicator disconnected';
            }
        }
        
        // 处理WebSocket消息
        function handleWebSocketMessage(data) {
            switch(data.type) {
                case 'client_connected':
                case 'client_disconnected':
                    loadDevices();
                    break;
                case 'message_received':
                    addMessageToLog(data);
                    break;
            }
        }
        
        // 切换标签页
        function switchTab(tabName) {
            // 更新标签按钮状态
            document.querySelectorAll('.tab').forEach(tab => {
                tab.classList.remove('active');
            });
            event.target.classList.add('active');
            
            // 更新内容面板
            document.querySelectorAll('.tab-panel').forEach(panel => {
                panel.classList.remove('active');
            });
            document.getElementById(tabName).classList.add('active');
            
            currentTab = tabName;
            
            // 加载对应数据
            switch(tabName) {
                case 'devices':
                    loadDevices();
                    break;
                case 'messages':
                    loadMessages();
                    break;
                case 'database':
                    loadDatabaseStats();
                    break;
            }
        }
        
        // 加载设备列表
        async function loadDevices() {
            try {
                const response = await fetch('/api/devices');
                const devices = await response.json();
                
                const deviceGrid = document.getElementById('deviceGrid');
                const onlineCount = devices.filter(d => d.status === 'online').length;
                const offlineCount = devices.filter(d => d.status === 'offline').length;
                
                // 更新统计数据
                document.getElementById('onlineDevices').textContent = onlineCount;
                document.getElementById('offlineDevices').textContent = offlineCount;
                
                // 生成设备卡片
                deviceGrid.innerHTML = devices.map(device => `
                    <div class="device-card ${device.status}" onclick="openDeviceManagement('${device.name || device.device_id}')" style="cursor: pointer; transition: transform 0.2s ease;">
                        <div class="device-name">${device.name || device.device_id}</div>
                        <div class="device-status ${device.status}">${device.status === 'online' ? '在线' : '离线'}</div>
                        <p>最后活跃: ${device.last_seen ? new Date(device.last_seen).toLocaleString() : '未知'}</p>
                        <small style="color: #95a5a6;">ID: ${device.device_id}</small>
                        <div style="margin-top: 10px; color: #3498db; font-size: 14px;">点击进入管理 →</div>
                    </div>
                `).join('');
            } catch (error) {
                console.error('加载设备列表失败:', error);
            }
        }
        
        // 加载消息日志
        async function loadMessages() {
            try {
                const response = await fetch('/api/messages?limit=50');
                const messages = await response.json();
                
                const messageLog = document.getElementById('messageLog');
                document.getElementById('todayMessages').textContent = messages.length;
                
                messageLog.innerHTML = messages.map(msg => `
                    <div class="message-item ${msg.topic}">
                        <div class="message-time">${new Date(msg.timestamp).toLocaleString()}</div>
                        <div class="message-topic">主题: ${msg.topic}</div>
                        <div class="message-payload">${msg.payload}</div>
                        <small>客户端: ${msg.client_id}</small>
                    </div>
                `).join('');
            } catch (error) {
                console.error('加载消息日志失败:', error);
            }
        }
        
        // 加载数据库统计
        async function loadDatabaseStats() {
            try {
                const [boxesRes, recordsRes] = await Promise.all([
                    fetch('/api/boxes'),
                    fetch('/api/records?limit=10')
                ]);
                
                const boxes = await boxesRes.json();
                const records = await recordsRes.json();
                
                document.getElementById('boxCount').textContent = boxes.length;
                document.getElementById('recordCount').textContent = records.length;
                document.getElementById('totalRecords').textContent = records.length;
                
                // 更新记录表格
                const tbody = document.querySelector('#recordsTable tbody');
                tbody.innerHTML = records.map(record => `
                    <tr>
                        <td>${record.operationTime || record.updated_at}</td>
                        <td>${record.boxId}</td>
                        <td>${record.operator}</td>
                        <td>${record.actionType}</td>
                        <td>${record.accessMethod}</td>
                    </tr>
                `).join('');
            } catch (error) {
                console.error('加载数据库统计失败:', error);
            }
        }
        
        // 添加消息到日志
        function addMessageToLog(data) {
            if (currentTab !== 'messages') return;
            
            const messageLog = document.getElementById('messageLog');
            const messageItem = document.createElement('div');
            messageItem.className = `message-item ${data.topic}`;
            messageItem.innerHTML = `
                <div class="message-time">${data.timestamp}</div>
                <div class="message-topic">主题: ${data.topic}</div>
                <div class="message-payload">${data.payload}</div>
                <small>客户端: ${data.clientId}</small>
            `;
            
            messageLog.insertBefore(messageItem, messageLog.firstChild);
            
            // 限制显示数量
            if (messageLog.children.length > 50) {
                messageLog.removeChild(messageLog.lastChild);
            }
        }
        
        // 清空消息日志
        function clearMessages() {
            document.getElementById('messageLog').innerHTML = '';
        }
        
        // 发布消息
        async function publishMessage() {
            const topic = document.getElementById('publishTopic').value;
            const payload = document.getElementById('publishPayload').value;
            
            if (!topic || !payload) {
                alert('请填写主题和消息内容');
                return;
            }
            
            try {
                let parsedPayload;
                try {
                    parsedPayload = JSON.parse(payload);
                } catch {
                    parsedPayload = payload;
                }
                
                const response = await fetch('/api/publish', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json',
                    },
                    body: JSON.stringify({
                        topic: topic,
                        payload: parsedPayload
                    })
                });
                
                if (response.ok) {
                    alert('消息发布成功！');
                    document.getElementById('publishTopic').value = '';
                    document.getElementById('publishPayload').value = '';
                } else {
                    alert('消息发布失败');
                }
            } catch (error) {
                console.error('发布消息失败:', error);
                alert('发布消息失败: ' + error.message);
            }
        }
        
        // 使用模板
        function useTemplate(type) {
            const topicInput = document.getElementById('publishTopic');
            const payloadInput = document.getElementById('publishPayload');
            
            switch(type) {
                case 'heart':
                    topicInput.value = 'heart';
                    payloadInput.value = 'heartbeat from server';
                    break;
                case 'unlock':
                    topicInput.value = 'kaihong/devices/cmd/put';
                    payloadInput.value = JSON.stringify({
                        device: "box1",
                        command: {
                            switch: 1,
                            key: 1
                        },
                        timestamp: new Date().toISOString()
                    }, null, 2);
                    break;
                case 'status':
                    topicInput.value = 'kaihong/devices/properties/report';
                    payloadInput.value = JSON.stringify({
                        device: "box1",
                        command: {
                            status: "query"
                        },
                        timestamp: new Date().toISOString()
                    }, null, 2);
                    break;
            }
        }
        
        // 打开设备管理页面
        function openDeviceManagement(deviceName) {
            window.location.href = `/device-management.html?device=${encodeURIComponent(deviceName)}`;
        }
        
        // 页面加载完成后初始化
        document.addEventListener('DOMContentLoaded', function() {
            // 先尝试WebSocket连接
            initWebSocket();
            
            // 立即加载数据
            loadDevices();
            loadMessages();
            
            // 定期刷新数据（无论WebSocket是否连接）
            setInterval(() => {
                if (currentTab === 'devices') {
                    loadDevices();
                } else if (currentTab === 'messages') {
                    loadMessages();
                } else if (currentTab === 'database') {
                    loadDatabaseStats();
                }
            }, 2000); // 每2秒刷新一次
            
            console.log('🚀 Web界面初始化完成');
        });
    </script>
</body>
</html>